/**
 * $Revision: 1.0 $
 * $Author: Geln Yang $
 * $Date: Jun 30, 2009 9:52:25 AM $
 *
 * Author: Eric Yang
 * Date  : Jun 30, 2009 9:52:25 AM
 *
 */
package c4j.project.report;

import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import c4j.file.FileUtils;
import c4j.file.ITextFileWriter;

/**
 * @author Eric Yang
 * @version 1.0
 */
public class ProjectReporter {
	private static final String charset = "utf-8";

	private static final String AUTHOR_PATTERN_STR = "(@|$)(A|a)uthor(:| ).+";

	private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

	public static final String BASE_DIRECTORY = "base_directory";

	public static final String OUTPUT_DIRECTORY = "output_directory";

	public static final String FILTER_DIRECTORIES = "filter_directory";

	public static final String DEFAULT_AUTHOR = "default_author";

	public static final String PROJECT_MODULE = "project_module";

	@SuppressWarnings("unchecked")
	public static void getJavaFilesHtmlList(Map<String, Object> parameters) throws IOException {
		String baseDir = (String) parameters.get(BASE_DIRECTORY);
		Set<String> filterDirs = (Set<String>) parameters.get(FILTER_DIRECTORIES);
		String projectModule = (String) parameters.get(PROJECT_MODULE);
		String outputDir = (String) parameters.get(OUTPUT_DIRECTORY);
		String defAuthor = (String) parameters.get(DEFAULT_AUTHOR);

		String pattern = ".*\\.java";

		File file = getSystemFileDoc(getHTMLFileList(baseDir, pattern, filterDirs, projectModule, defAuthor, "程式", true));

		if (!outputDir.endsWith(File.separator))
			outputDir += File.separator;
		FileUtils.moveFile(file, outputDir + "project_java_files.html");
	}

	@SuppressWarnings("unchecked")
	public static void getJspFilesHtmlList(Map<String, Object> parameters) throws IOException {
		String baseDir = (String) parameters.get(BASE_DIRECTORY);
		Set<String> filterDirs = (Set<String>) parameters.get(FILTER_DIRECTORIES);
		String projectModule = (String) parameters.get(PROJECT_MODULE);
		String outputDir = (String) parameters.get(OUTPUT_DIRECTORY);
		String defAuthor = (String) parameters.get(DEFAULT_AUTHOR);

		String pattern = ".*\\.jsp";

		File file = getSystemFileDoc(getHTMLFileList(baseDir, pattern, filterDirs, projectModule, defAuthor, "程式", true));

		if (!outputDir.endsWith(File.separator))
			outputDir += File.separator;
		FileUtils.moveFile(file, outputDir + "project_jsp_files.html");
	}

	@SuppressWarnings("unchecked")
	public static void getConfigurationFilesHtmlList(Map<String, Object> parameters) throws IOException {

		String baseDir = (String) parameters.get(BASE_DIRECTORY);
		Set<String> filterDirs = (Set<String>) parameters.get(FILTER_DIRECTORIES);
		String projectModule = (String) parameters.get(PROJECT_MODULE);
		String outputDir = (String) parameters.get(OUTPUT_DIRECTORY);
		String defAuthor = (String) parameters.get(DEFAULT_AUTHOR);

		String pattern = ".*\\.((xml)|(properties)|(dtd)|(ftl)|(txt))";

		File file = getSystemFileDoc(getHTMLFileList(baseDir, pattern, filterDirs, projectModule, defAuthor, "文件", false));
		outputDir = FileUtils.initDirPath(outputDir);
		FileUtils.moveFile(file, outputDir + "project_configuration_files.html");
	}
	
	@SuppressWarnings("unchecked")
	public static void getAllFilesHtmlList(Map<String, Object> parameters) throws IOException {

		String baseDir = (String) parameters.get(BASE_DIRECTORY);
		Set<String> filterDirs = (Set<String>) parameters.get(FILTER_DIRECTORIES);
		String projectModule = (String) parameters.get(PROJECT_MODULE);
		String outputDir = (String) parameters.get(OUTPUT_DIRECTORY);
		String defAuthor = (String) parameters.get(DEFAULT_AUTHOR);

		String pattern = ".*\\..*";

		File file = getSystemFileDoc(getHTMLFileList(baseDir, pattern, filterDirs, projectModule, defAuthor, "文件", false));
		outputDir = FileUtils.initDirPath(outputDir);
		FileUtils.moveFile(file, outputDir + "all_files.html");
	}

	public static StringBuffer getHTMLFileList(String baseDir, String pattern, Set<String> filterDirs,
			String projectModule, String defAuthor, String fileType, boolean isConfigFile) throws IOException {
		if (baseDir.endsWith(File.separator))
			baseDir += File.separator;
		StringBuffer buffer = new StringBuffer();
		buffer.append("<html><header>");
		buffer.append("<meta http-equiv=Content-Type content=\"text/html;charset=UTF-8\"><title>File list -- ");
		buffer.append(baseDir + "[" + pattern + "]</title>");
		buffer.append("</header>");
		buffer.append("<body>");
		buffer.append("<table border=\"1\" style=\"width:800px\"><tbody>");
		buffer.append("<tr><th style=\"width:10px\">Index</th>");
		buffer.append("<th style=\"width:3000px\">File Path</th>");
		buffer.append("<th style=\"width:100px\">Comment</th>");
		buffer.append("<th style=\"width:100px\">Date</th><th style=\"width:100px\">author</th></tr>");
		Index index = new Index();
		buffer.append(getFileList(baseDir, "", pattern, index, filterDirs, projectModule, defAuthor, fileType, isConfigFile));
		buffer.append("</tbody></table></body></html>");
		return buffer;
	}

	public static StringBuffer getFileList(String baseDir, String subDir, String pattern, Index index,
			Set<String> filterDirs, String projectModule, String defAuthor, String fileType, boolean isConfigFile) throws IOException {

		subDir = FileUtils.initDirPath(subDir);
		StringBuffer buffer = new StringBuffer();
		File dir = new File(baseDir + subDir);
		String currentDirName = getCurrentModule(subDir, projectModule);
		File[] files = dir.listFiles();
		List<File> childDirs = new ArrayList<File>();
		if (files != null) {
			for (int i = 0; i < files.length; i++) {
				File file = files[i];
				if (file.isDirectory()) {
					childDirs.add(file);
					continue;
				}
				String fileName = file.getName();
				String date = dateFormat.format(new Date(file.lastModified()));
				String author = defAuthor;
				String fileContent = new String(FileUtils.getFileContent(file));
				Matcher matcher = Pattern.compile(AUTHOR_PATTERN_STR).matcher(fileContent);
				if (matcher.find())
					author = matcher.group(0).substring(8);
				if (fileName.matches(pattern)) {
					buffer.append("<tr>"//
							+ "<td>" + index.index++
							+ "</td>"//
							+ "<td>" + subDir + file.getName()
							+ " </td>"//
							+ "<td>" + currentDirName + " 模块 "
							+ getOutputFileName(fileName, fileType, isConfigFile)
							+ "</td>"//
							+ "<td>" + date + " </td>"//
							+ "<td>" + author + " </td>"//
							+ "</tr>");
				}

			}

			for (int i = 0; i < childDirs.size(); i++) {
				String subDirName = childDirs.get(i).getName();
				if (!filterDirs.contains(subDirName))
					buffer.append(getFileList(baseDir, subDir + childDirs.get(i).getName(), pattern, index, filterDirs,
							projectModule, defAuthor, fileType, isConfigFile));
			}
		}
		return buffer;
	}

	public static File getSystemFileDoc(final StringBuffer buffer) throws IOException {
		return FileUtils.writeBufferedTempTextFile(System.currentTimeMillis() + "", ".html", charset,
				new ITextFileWriter() {
					public void write(BufferedWriter writer) throws IOException {
						writer.write(buffer.toString());
					}
				});
	}

	private static String getCurrentModule(String subDir, String projectModule) {
		int projectIndex = subDir.indexOf(projectModule);
		String currentDirName = subDir;
		if (projectIndex > 0)
			currentDirName = currentDirName.substring(projectIndex + projectModule.length(), currentDirName.length());
		currentDirName = currentDirName.replace(File.separator, " ");
		if (currentDirName.endsWith("impl ")) {
			currentDirName = currentDirName.substring(0, currentDirName.length() - 5);
		}
		currentDirName = currentDirName.toUpperCase();
		if (currentDirName.equals(""))
			currentDirName = "DEFAULT";
		return currentDirName;
	}

	private static String getOutputFileName(String fileName, String fileType, boolean isConfigFile) {
		String result = "";
		if (!isConfigFile) {
			if (fileName.endsWith(".properties"))
				result = "资源配置";
			else if (fileName.endsWith(".ftl"))
				result = "模板配置";
			else if (fileName.endsWith(".txt"))
				result = "说明";
			else if (fileName.endsWith(".dtd"))
				result = "xml定义";
			else if (fileName.endsWith(".hbm.xml"))
				result = "hbm配置";
			else if (fileName.endsWith(".xml"))
				result = "配置";
			return fileName + " " + result + fileType;
		} else {

			fileName = fileName.substring(0, fileName.lastIndexOf("."));
			if (fileName.startsWith("Test"))
				result = fileName.substring(4, fileName.length()) + "测试";
			else if (fileName.startsWith("I") && fileName.toCharArray()[0] < 'a') {
				result = fileName + "接口";
			} else {

				StringBuilder nameBuilder = new StringBuilder();
				boolean isPreUpperChar = false;
				for (char c : fileName.toCharArray()) {
					if (c < 'a') {
						if (!isPreUpperChar) {
							nameBuilder.append(" ");
							isPreUpperChar = false;
						}
						isPreUpperChar = true;
					} else {
						isPreUpperChar = false;
					}

					nameBuilder.append(c);
				}
				result = nameBuilder.toString();
			}

			return result + "程式";

		}

	}

	public static class Index {
		int index = 1;

		public int getIndex() {
			return index;
		}

		public void setIndex(int index) {
			this.index = index;
		}

	}
}
